public class MySingleList {
    //自己模拟实现一个单链表；‘
    static class Node{
        public int val;
        public Node next;
        public Node(int val){
            this.val=val;
        }

        @Override
        public String toString() {
            return "Node{" +
                    "val=" + val +
                    ", next=" + next +
                    '}';
        }
    }
    public Node head;
    //1.进行单列表的创建；
    public void createListNode(){
        Node node1=new Node(12);
        Node node2=new Node(23);
        Node node3=new Node(34);
        Node node4=new Node(45);
        Node node5=new Node(56);
        node1.next=node2;
        node2.next=node3;
        node3.next=node4;
        node4.next=node5;
        this.head=node1;
    }
    //2.进行列表节点个数的统计；
    public int size(){
        int count=0;
        Node cur=head;
        while(cur!=null){
            count++;
            cur=cur.next;
        }
        return count;
    }
    //3.头插法；
    public void addFirst(int date){
        Node newNode=new Node(date);
            newNode.next=head;
            head=newNode;
    }
    //4.尾插法；
    public void addLast(int date){
        Node newNode=new Node(date);
        if(head==null){
            newNode.next=head;
            head=newNode;
        }
        Node cur=head;
        while(cur.next!=null){
            cur=cur.next;
        }
        cur.next=newNode;
    }
    //5.进行向任意指定的位置插入节点；
    public void insertNode(int index,int date){
        if(head==null){
            return;
        }
        int len=size();
        if(index<0||index>len){
            System.out.println("要插入的位置不合法");
            return;
        }
        //头位置；
        if(index==0){
            addFirst(date);
            return;
        }
        //尾位置；
        if(index==len){
            addLast(date);
        }
        //中间位置；
        Node newNode=new Node(date);
        Node cur=searchIndex(index);
        if(cur==null){
            return;
        }
        newNode.next=cur.next;
        cur.next=newNode;
    }
    //6.进行寻找某个位置的结点；
    public Node searchIndex(int index){
        int len=size();
        if(index<0||index>len){
            return null;
        }
        Node cur=head;
        int count=0;
        while(count!=index-1){
            cur=cur.next;
            count++;
        }
        return cur;
    }
    //7.进行判断单列表中是否包含某个节点；
    public boolean contains(int key){
        if(head==null){
            return false;
        }
        Node cur=head;
        while(cur!=null){
            if(cur.val==key){
                return true;
            }
            cur=cur.next;
        }
        return false;
    }
    //8.进行打印单列表；
    public void disPlay(){
        Node cur=head;
        while(cur!=null){
            System.out.print(cur.val+" ");
            cur=cur.next;
        }
        System.out.println();
    }
    //9.删除第一次出现值为key的节点；
    public void deleteFistKey(int key){
        if(head==null){
            return;
        }
        if(head.val==key){
            head=head.next;
            return;
        }
        //程序执行到这里,说明头节点不属于我们要删除的节点；
        //接下来，进行通过key寻找我们要删除节点的前一个节点，
        // 方便我们进行删除我们想要删除的节点，以及后续链表的连贯性；
        Node prev=findkeyNode(key);
        Node del=prev.next;
        prev.next=del.next;
    }
    //10.通过给定的节点值，进行寻找这个节点的前一个节点；
    public Node findkeyNode(int key){
        if(head==null){
            return null;
        }
        Node prev=head;
        while(prev.next!=null){
            if(prev.next.val==key){
                return prev;
            }
            prev=prev.next;
        }
        return prev;
    }
    //11，进行删除所有值为key的节点；
    //方法思路：1.首先进行判断单列表是否为空；
    //////////2.其次进行判定除了头节点的其余节点的值是否为空；
    /////////注意：
    // 在进行遍历寻找的过程中要进行记录前一个节点，防止我们删除了要删除的节点找不到前一个节点的情况；
    public void remove(int key){
        if(head==null){
            return;
        }
        Node prev=head;
        Node cur=head.next;
        while(cur!=null){
            if(cur.val==key){
                prev.next=cur.next;
                cur=cur.next;
            }else{
                prev=cur;
                cur=cur.next;
            }
        }
        //最后进行判断头节点是否是我们要删除的节点；
        //如果一开始进行判断头结点的话，并且头结点是要删除的节点，
        // 删除完毕我们就无法进行后续操作了，所以这时就需要我们最后进行判定头节点的情况；
        if(head.val==key){
            head=head.next;
        }
    }




}
